package com.example.administrator.testproject.Tag;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.ViewTreeObserver;

import com.example.administrator.testproject.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by shengfh on 2018/1/18.
 */

public class TagTextView extends android.support.v7.widget.AppCompatTextView {

    public static class TagType {
        static int TYPE_FLAG = 0;//标签
        static int TYPE_DRAWABLE = 1;//图片
        static int TYPE_TEXT_COLOR = 2;//带颜色字体
    }

    private int availableTextWidth;
    private int maxLine;
    private int paddingLeft;
    private int paddingRight;
    private int bufferWidth;
    private int width;
    private TextPaint paint;

    private float textSize;
    private float flagTextSize;
    private int textColor;
    private List<FlagBean> leftFlags = new ArrayList<>();
    private List<FlagBean> rightFlags = new ArrayList<>();
    private String contentString;
    private String spacer = "&";
    private boolean isMeasure;


    public TagTextView(Context context) {
        super(context);
    }

    public TagTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(attrs);
    }

    public TagTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }


    private void initView(@Nullable AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.TagTextView);
        textSize = typedArray.getDimension(R.styleable.TagTextView_Ttext_Size, 14);
        textColor = typedArray.getColor(R.styleable.TagTextView_Ttext_Color, getResources().getColor(R.color.gray_3));
        flagTextSize = typedArray.getDimension(R.styleable.TagTextView_Tflag_textSize, 10);
        maxLine = typedArray.getInt(R.styleable.TagTextView_Tflag_max_line, 0);
        spacer = typedArray.getString(R.styleable.TagTextView_Tflag_spacer);
        if (TextUtils.isEmpty(spacer)) spacer = "&";
        typedArray.recycle();

        paint = getPaint();
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                if (availableTextWidth == 0 && getWidth() > 0) {
                    width = getWidth();
                    paddingLeft = getPaddingLeft();
                    paddingRight = getPaddingRight();
                    paint.setTextSize(textSize);
                    isMeasure = true;
                    draw();
                    if (Build.VERSION.SDK_INT >= 16) {
                        getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
                }
            }
        });
    }

    public void draw() {
        if (!isMeasure) return;
        setText("");
        //缓冲区长度，空出两个字符的长度来给最后的省略号及图片
        bufferWidth = (int) paint.getTextSize() * (rightFlags.size());
        if (TextUtils.isEmpty(contentString))
            return;
        StringBuffer flagBuffer = new StringBuffer();
        for (int i = 0; i < leftFlags.size(); i++) {
            flagBuffer.append(leftFlags.get(i).getTxt());
            flagBuffer.append(" ");
        }
        // 根据长度截取出剪裁后的文字
        contentString = flagBuffer + contentString;
        paint.setTextSize(textSize);
        String ellipsizeStr = contentString;
        if (maxLine > 0) {
            // 计算出2行文字所能显示的长度
            availableTextWidth = (width - paddingLeft - paddingRight) * maxLine - bufferWidth;
            ellipsizeStr = (String) TextUtils.ellipsize(contentString, paint, availableTextWidth - textSize, TextUtils.TruncateAt.END);
        }

        StringBuffer rightBuffer = new StringBuffer();
        for (int i = 0; i < rightFlags.size(); i++) {
            if (rightFlags.get(i).getType() == TagType.TYPE_DRAWABLE) {
                rightBuffer.append(spacer);
                rightBuffer.append("im" + i);
                rightFlags.get(i).setTxt("im" + i);
            } else if (rightFlags.get(i).getType() == TagType.TYPE_FLAG) {
                rightBuffer.append(" ");
                rightBuffer.append(rightFlags.get(i).getTxt());
            } else if (rightFlags.get(i).getType() == TagType.TYPE_TEXT_COLOR) {
                rightBuffer.append(rightFlags.get(i).getTxt());
            }
        }

        SpannableStringBuilder ssBuilder = new SpannableStringBuilder(ellipsizeStr + rightBuffer);
        for (FlagBean flagBean : leftFlags) {
            pickFlagType(flagBean, ssBuilder);
        }
        for (FlagBean flagBean : rightFlags) {
            pickFlagType(flagBean, ssBuilder);
        }
        //temp "&"
        int a = ssBuilder.toString().indexOf(spacer);
        while (a != -1) {
            ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.TRANSPARENT);
            ssBuilder.setSpan(colorSpan, a, a + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
            a = ssBuilder.toString().indexOf(spacer, a + 1);
        }
        setText(ssBuilder);
    }

    private void pickFlagType(FlagBean flagBean, SpannableStringBuilder ssBuilder) {
        int start = 0;
        int end = 0;
        if (flagBean.getType() == TagType.TYPE_FLAG) {
            start = ssBuilder.toString().indexOf(flagBean.getTxt());
            end = start + flagBean.getTxt().length();
            if (start >= ssBuilder.toString().length()) return;
            float lineHeight = getLineSpacingExtra();
            ssBuilder.setSpan(new RadiusBackgroundSpan(flagBean.getTextColor(),
                    flagTextSize, flagBean.isFull, 10, lineHeight), start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        } else if (flagBean.getType() == TagType.TYPE_DRAWABLE) {
            start = ssBuilder.toString().indexOf(flagBean.getTxt());
            end = start + flagBean.getTxt().length();
            Drawable drawable = flagBean.getDrawable();
            if (drawable != null) {
                drawable.setBounds(0, 0, (int) textSize, (int) textSize);
                ImageSpan imgSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
                ssBuilder.setSpan(imgSpan, start, end, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        } else if (flagBean.getType() == TagType.TYPE_TEXT_COLOR) {
            start = ssBuilder.toString().indexOf(flagBean.getTxt());
            if (start >= 0) {
                end = start + flagBean.getTxt().length();
                ForegroundColorSpan colorSpan = new ForegroundColorSpan(flagBean.getTextColor() == null ?
                        textColor : flagBean.getTextColor());
                ssBuilder.setSpan(colorSpan, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
            }
        }
    }

    /**
     * 添加带边线，或者全背景的flag
     *
     * @param flag
     * @param textColor
     * @param isFulll   是否是全颜色的背景 false  color为边线颜色，true color为背景颜色
     * @param gravity   位置，目前只支持左右
     * @return
     */
    public TagTextView addFlagText(String flag, int textColor, boolean isFulll, int gravity) {
        if (TextUtils.isEmpty(flag) || TextUtils.isEmpty(flag.trim())) return this;
        FlagBean flagBean = new FlagBean();
        flagBean.setTxt("^" + flag.trim() + "^");
        flagBean.setGravity(Gravity.LEFT);
        flagBean.setTextColor(textColor);
        flagBean.setType(TagType.TYPE_FLAG);
        flagBean.isFull = isFulll;
        if (gravity == Gravity.LEFT) {
            if (!leftFlags.contains(flagBean))
                leftFlags.add(flagBean);
        } else if (gravity == Gravity.RIGHT) {
            if (!rightFlags.contains(flagBean))
                rightFlags.add(flagBean);
        }
        return this;
    }

    /**
     * 添加一个图片，图片大小为一个文字大小
     *
     * @param vectorDrawableId
     * @param gravity
     * @return
     */
    public TagTextView addFlagDrawable(@DrawableRes int vectorDrawableId, int gravity) {
        FlagBean flagBean = new FlagBean();
        flagBean.setGravity(gravity);
//        if (view != null) {
        flagBean.setDrawable(getContext().getResources().getDrawable(vectorDrawableId));
//        }
        flagBean.setType(TagType.TYPE_DRAWABLE);
        if (gravity == Gravity.LEFT) {
            leftFlags.add(flagBean);
        } else if (gravity == Gravity.RIGHT) {
            rightFlags.add(flagBean);
        }
        return this;
    }

    /**
     * 添加带颜色的文字
     *
     * @param textColor
     * @param tex
     * @param gravity
     * @return
     */
    public TagTextView addFlagColorText(int textColor, String tex, int gravity) {
        FlagBean flagBean = new FlagBean();
        flagBean.setGravity(gravity);
        flagBean.setTxt(tex);
        flagBean.setType(TagType.TYPE_TEXT_COLOR);
        flagBean.setTextColor(textColor);
        if (gravity == Gravity.LEFT) {
            leftFlags.add(flagBean);
        } else if (gravity == Gravity.RIGHT) {
            rightFlags.add(flagBean);
        }
        return this;
    }

    /**
     * 添加文本信息
     *
     * @param contentString
     * @return
     */
    public TagTextView setContentText(CharSequence contentString) {
        this.contentString = contentString.toString();
        return this;
    }

    /**
     * 添加文本信息
     *
     * @param contentString
     * @param spacerCount   字符左右间距，通过添加固定字符进行增加间距
     * @return
     */
    public TagTextView setContentText(CharSequence contentString, int spacerCount) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < spacerCount; i++) {
            buffer.append(spacer);
        }
        this.contentString = buffer.toString() + contentString + buffer.toString();
        return this;
    }

    public void build() {
        draw();
    }

    public TagTextView builder() {
        setText("");
        leftFlags.clear();
        rightFlags.clear();
        contentString = "";
        return this;
    }

    class FlagBean {

        private int type;// 1 flag 2 drawable 3 textColor
        private int gravity;//只识别左右

        private String txt;
        private int Res;
        private Drawable drawable;
        private Bitmap bitmap;
        private Float padding;
        private Integer textColor;
        private Float textSize;
        private boolean isFull;

        public boolean isFull() {
            return isFull;
        }

        public void setFull(boolean full) {
            isFull = full;
        }


        public Float getTextSize() {
            return textSize;
        }

        public void setTextSize(Float textSize) {
            this.textSize = textSize;
        }

        public Integer getTextColor() {
            return textColor;
        }

        public void setTextColor(Integer textColor) {
            this.textColor = textColor;
        }

        public Float getPadding() {
            return padding;
        }

        public void setPadding(Float padding) {
            this.padding = padding;
        }

        public int getGravity() {
            return gravity;
        }

        public void setGravity(int gravity) {
            this.gravity = gravity;
        }

        public String getTxt() {
            return txt;
        }

        public void setTxt(String txt) {
            this.txt = txt;
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public int getRes() {
            return Res;
        }

        public void setRes(int res) {
            Res = res;
        }

        public Drawable getDrawable() {
            return drawable;
        }

        public void setDrawable(Drawable drawable) {
            this.drawable = drawable;
        }

        public Bitmap getBitmap() {
            return bitmap;
        }

        public void setBitmap(Bitmap bitmap) {
            this.bitmap = bitmap;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof FlagBean) {
                FlagBean flagBean = (FlagBean) obj;
                if (getTxt().contains(flagBean.getTxt())) {
                    return true;
                }
            }
            return super.equals(obj);
        }
    }
}
